package com.zf.until_now;

/**
 * jdk17新特性，正式推出
 * - 密封类
 * - 密封类支持子类是record类
 */
public class Jdk17Release {
    public static void main(String[] args) {
        testSealed();
    }

    /**
     * 密封类 sealed，用于限制类的继承结构。
     * 密封类 sealed，使用 permits 关键字指定类或接口只能被哪些类继承或者实现，用在extends和implements之后。
     * 如果没有 permits 关键字指定实现类或接口，则任何类或接口都能继承或实现该密封类。
     * 如果接口或类被 sealed 标记，则一定要被实现或者继承，否者报错。
     * 且子类只能用 final（不能被继承） 或者 non-sealed （可以被继承） 或者 sealed（密封类）修饰
     */
    public static void testSealed() {
        new Dog().sleep();
        new Cat().sleep();
        new Snake().sleep();
    }

    // permits关键字 指定Animal类只能被 Dog、Cat、Snake 继承，其他类不行
    static sealed class Animal permits Dog, Cat, Snake {
        public void sleep() {
            System.out.println(this.getClass().getName()+"睡觉了");
        }
    }

    static final class Dog extends Animal {
    }

    // 子类不密封，可以被任何类继承
    static non-sealed class Cat extends Animal {
    }

    static class Cat01 extends Cat {}

    // 子类密封，只定制继承的类
    static sealed class Snake extends Animal permits BigSnake {
    }

    static final class BigSnake extends Snake {
    }


    // 没有使用 permits 指定子类，任何类或接口都能继承或实现
    static sealed class Human {}

    static final class BigHuman extends Human {}

    // 密封接口，子类是 record 类
    sealed interface DataBase permits DataBaseUpdate {
        default void printDb() {
            System.out.println("db");
        }
    }

    //
    record DataBaseUpdate<T>(T name) implements DataBase {
    }


}
